require 'rest-client'
require 'json'
require 'base64'


class BrakemanAnalysis
  def initialize(repo, head_sha, bare_sha, access_token_str)

    @repo = repo
    @access_token = Base64.decode64(access_token_str)[0...32]
    @head_sha = head_sha
    @bare_sha = bare_sha
  end

  def exec
    create_brakeman
    initiate_check_run
  end

  def create_brakeman
    data = {
      details_url: 'https://gitee.com/liwen',
      name: 'Brakeman 安全检测',
      head_sha: @head_sha
    }
    url = "https://gitee.com/api/v5/repos/#{@repo}/check-runs"
    @response_json = RestClient.post url, data, { 'Private-Token' => @access_token }
    @response = JSON.parse(@response_json)
    @check_run_id = @response['id']
    puts "@check_run_id => #{@check_run_id}"
  end

  def initiate_check_run
    url = "https://gitee.com/api/v5/repos/#{@repo}/check-runs/#{@check_run_id}"
    data = {
      access_token: @access_token,
      status: 'in_progress'
    }
    RestClient.patch url, data

    diff_paths = `git diff --name-only #{@head_sha} #{@bare_sha}`
    puts "diff_paths: #{diff_paths}"
    @report = `brakeman -f json --only-files #{diff_paths.split($/).join(',')}`
    @output = JSON.parse @report

    annotations = []

    if @output['errors'] == 0
      conclusion = 'success'
    else
      conclusion = 'success'
      annotation_level_map = {"High" => 'failure', "Medium" => 'warning', "Weak" => 'notice'}

      @output['warnings'].each do |warning|

        start_line = end_line = warning['line']
        title = "#{warning["confidence"]} - #{warning["warning_type"]}"
        message = warning["message"]
        file = warning["file"]
        annotation_level = annotation_level_map[warning["confidence"]]
        puts "warning-> #{warning["confidence"]}"
        raw_details = warning["link"]
        if annotation_level == "failure"
          conclusion = "failure"
        elsif 'failure' != conclusion && 'warning' == annotation_level
          conclusion = "neutral"
        end

        annotation = {
          title: title,
          path: file,
          start_line: start_line,
          end_line: end_line,
          annotation_level: annotation_level,
          message: message,
          raw_details: raw_details
        }
        annotations.push(annotation)
      end
    end

    summary = "Brakeman summary\n - Controllers count: #{@output['scan_info']['number_of_controllers']}\n- Models count: #{@output['scan_info']['number_of_models']}\n- Templates count: #{@output['scan_info']['number_of_templates']}\n- Security Warnings count: #{@output['scan_info']['security_warnings']}"
    text = "Brakeman version: #{@output['scan_info']['brakeman_version']}"

    url = "https://gitee.com/api/v5/repos/#{@repo}/check-runs/#{@check_run_id}"
    data = {
      access_token: @access_token,
      conclusion: conclusion,
      details_url: "http://brakemanscanner.org/",
      output: {
        title: 'Brakeman安全检测',
        summary: summary,
        text: text,
        annotations: annotations
      }
    }
    puts data
    reposponse = RestClient.patch url, data
    puts "finished: #{reposponse}"
  end
end

inputted_strings = ARGV
if ARGV.empty?
  puts "nothing :("
else
  repo, head_sha, bare_sha, access_token_str = inputted_strings
  puts "repo: #{repo}, head_sha: #{head_sha}, bare_sha: #{bare_sha}"
  BrakemanAnalysis.new(repo, head_sha, bare_sha, access_token_str).exec
end
